#include "stdlib.hpp"
#include <purewell/filesystemstatus.hpp>

namespace purewell
{

#define _xchg(x) ((struct statvfs*)(x))
#define _cxchg(x) ((const struct statvfs*)(x))
#define _imp_getXXX(name,stname,rtype) rtype\
	PWFileSystemStatus::get##name (void) const\
	{ return ((const struct statvfs*)m_pData)->f_##stname; }

_imp_getXXX(BlockSize, bsize, size_t);
_imp_getXXX(FragmentSize, frsize, size_t);
_imp_getXXX(Blocks, blocks, fsblkcnt_t);
_imp_getXXX(FreeBlocks, bfree, fsblkcnt_t);
_imp_getXXX(AvailableBlocks, bavail, fsblkcnt_t);
_imp_getXXX(INodes, files, fsblkcnt_t);
_imp_getXXX(FreeINodes, ffree, fsblkcnt_t);
_imp_getXXX(AvailableINodes, favail, fsblkcnt_t);
_imp_getXXX(ID, fsid, size_t);
_imp_getXXX(Flags, flag, size_t);
_imp_getXXX(MaxFileNameSize, namemax, size_t);

PWFileSystemStatus::PWFileSystemStatus()
{
	memset(m_pData, 0x00, PWFSSTAT_MAX_LEN);
}

PWFileSystemStatus::PWFileSystemStatus(const PWFileSystemStatus& fs)
{
	memcpy(m_pData, fs.m_pData, PWFSSTAT_MAX_LEN);
}

PWFileSystemStatus::PWFileSystemStatus(const char* path)
{
	getStatus(path);
}

PWFileSystemStatus::PWFileSystemStatus(int fd)
{
	getStatus(fd);
}

PWFileSystemStatus::PWFileSystemStatus(const PWFile& file)
{
	getStatus(file);
}

PWFileSystemStatus::~PWFileSystemStatus()
{
}

PWFileSystemStatus&
PWFileSystemStatus::operator = ( const PWFileSystemStatus& fs )
{
	memcpy(m_pData, fs.m_pData, PWFSSTAT_MAX_LEN);
	return *this;
}

bool
PWFileSystemStatus::getStatus(const PWFile& file)
{
	return 0 == fstatvfs(file.getHandle(), _xchg(m_pData));
}

bool
PWFileSystemStatus::getStatus(int fd)
{
	return 0 == fstatvfs(fd, _xchg(m_pData));
}

bool
PWFileSystemStatus::getStatus(const char* path)
{
	return 0 == statvfs(path, _xchg(m_pData));
}

bool
PWFileSystemStatus::isNoSUID(void) const
{
	return 0 != ((_cxchg(m_pData)->f_flag)&ST_NOSUID);
}

bool
PWFileSystemStatus::isReadOnly(void) const
{
	return 0 != ((_cxchg(m_pData)->f_flag)&ST_RDONLY);
}

};//namespace purewell

